generic
  -- component type, which can be almost any type
  type component_t is private;

  -- dimension of the vector
  dimension : positive;

  -- a value of component type that represents zero
  zero : component_t;

  -- operators defined on component type required by vector operations
  -- duplicate formal subprogram names indicate that named association
  -- is not allowed and should use parameter passing in explicit order
  -- instead
  with function "+"(lhs, rhs: component_t) return component_t is <>;
  with function "-"(lhs, rhs: component_t) return component_t is <>;
  with function "*"(lhs, rhs: component_t) return component_t is <>;
  with function "-"(c : component_t) return component_t is <>;

package ariane.maths.vector is

  -- the type of the array used to store the component values of the vector
  type components_t is array (1..dimension) of component_t;

  -- declaration of vector object provided to the user
  type object is tagged private;

  -- creates an object and initializes it with specified data
  function create(components : components_t := (others=>zero)) return object;

  -- constructor of vector object
  -- as vector type here is a constrained, we can use procedure-based
  -- initializer-styled constructor on an object defined unassigned
  -- the component array argument is optional which when absent is
  -- an array of default values
  procedure set(o : in out object; components : components_t := (others=>zero));

  -- setter that assigns value to specific component
  procedure set(o : in out object; index : positive; val : component_t);

  -- getter that returns value of specific component
  function get(o : in object; index : positive) return component_t;

  -- returns the result of adding vector lhs to rhs
  function "+"(lhs, rhs: object) return object;

  -- returns the result of subtracting vector rhs from lhs
  function "-"(lhs, rhs: object) return object;

  -- returns the inner product of the two vectors
  function "*"(lhs, rhs: object) return component_t;

  -- returns the negative of the given object
  function "-"(o : object) return object;

  -- returns the sum of all components of the given vector object
  function sum(o : object) return component_t;

  -- returns the length of vector
  function length(o : object) return positive;

private

  -- details of the data structure of the vector object
  type object is tagged record
    components : components_t;
  end record;

end ariane.maths.vector;
